#pragma once

#include "ServerImp.h"
#include "HeartBeatChannelMaps.h"
#include "TimerTask.h"

namespace frame {
namespace imp {

class HandlerImp;

class HeartBeatTimerTask : public ITimerTask {
public:
    HeartBeatTimerTask(ServerImp * serverImp);
    ~HeartBeatTimerTask() override;

    void handle(Timer * timer) override;

private:
    ServerImp * serverImp;
};

class HeartBeatServerImp :  public ServerImp {
public:
    HeartBeatServerImp(ServerImp * serverImp, uint64_t maxReadTimespan, uint64_t maxWriteTimespan);
    ~HeartBeatServerImp() override;

    void setHandler(HandlerImp * handler) override;
    
    int start() override;
    int run() override ;
    void stop() override;

    uint64_t addTimerTask(ITimerTask * task, uint64_t timespan) override ;
    void removeTimerTask(uint64_t timerId) override ;


    // ************************************************

    uint64_t getDefaultMaxHeartBeatReadTimespan() const {
        return defaultMaxHeartBeatReadTimespan;
    }
    uint64_t getDefaultMaxHeartBeatWriteTimespan() const {
        return defaultMaxHeartBeatWriteTimespan;
    }

    HeartBeatChannelMaps & getChannels(){
        return channels;
    }

    bool addChannel(ServerChannelImp * serverChannelImp);
    bool removeChannel(uint64_t channelId);
    HeartBeatChannelMaps::ChannelNode * getChannel(uint64_t channelId);

private:
    ServerImp * serverImp;
    HandlerImp * hbHandlerImp;
    ITimerTask * checkHeartBeatTimerTask;
    HeartBeatChannelMaps channels;

    uint64_t defaultMaxHeartBeatReadTimespan;
    uint64_t defaultMaxHeartBeatWriteTimespan;
};

} //end of namespace  imp
} //end of namespace  frame
